package gameBlock

import (
	"gitee.com/wchpub/dwSvrPub/dwProto"
	"gitee.com/wchpub/fnsvr/funcSless"
)

////////////////////////////////////////////////////////////
//游戏局内数据

type BlockType string

const (
	//数据块名称
	BlockName string = "game"
)

const (
	Key_GameStartTime BlockType = "gameStartTime" //游戏开始时间
	Key_LastSyncTime  BlockType = "lastSyncTime"  //上次同步时间
	Key_GameSeed      BlockType = "gameSeed"      //随机种子
	Key_LargestBall   BlockType = "largestBall"   //最大球编号

	Key_AllBalls  BlockType = "allBalls"  //场景中的所有球，不包含已经合成的
	Key_BallCount BlockType = "ballCount" //场景中累计产出的球数

	Key_ThemeId  BlockType = "themeId"  //主题id
	Key_RewardId BlockType = "rewardId" //胜利后可获得的奖励id v2已废弃

	Key_ErrTimes  BlockType = "errTimes"  //错误次数
	Key_IsGameEnd BlockType = "isGameEnd" //游戏是否结束

	Key_GuideEvents BlockType = "guideEvents" //新手指引存档事件号
	Key_GameId      BlockType = "gameId"      //游戏id
	Key_GameMode    BlockType = "gameMode"    //游戏模式
)

type Data struct {
	super *funcSless.Block[BlockType]
}

func (m *Data) PreLoad(keys ...BlockType) {
	m.super.PreLoad(keys...)
}

// 指引存档事件号
func (m *Data) GuideEvents() ([]int64, error) {
	re := []int64{}
	err := m.super.GetJson(Key_GuideEvents, &re)
	if err != nil {
		return nil, err
	}

	return re, nil
}

func (m *Data) SetGuideEvents(v []int64) error {
	return m.super.SetJson(Key_GuideEvents, v)
}

// 上次同步时间
func (m *Data) LastSyncTime() (int64, error) {
	return m.super.GetInt64(Key_LastSyncTime)
}

func (m *Data) SetLastSyncTime(v int64) {
	m.super.SetInt64(Key_LastSyncTime, v)
}

// 单局游戏开始时间
func (m *Data) GameStartTime() (int64, error) {
	return m.super.GetInt64(Key_GameStartTime)
}

// 重置局内游戏
func (m *Data) ResetGame(gStartTime int64) error {
	m.SetLargestBall(1)
	m.SetAllBalls(0)
	m.SetBallCount(0)
	m.super.SetInt64(Key_GameStartTime, gStartTime)
	m.SetLastSyncTime(gStartTime)
	m.super.SetInt(Key_ErrTimes, 0)
	m.SetThemeId(0)
	m.SetIsGameEnd(false)

	return nil
}

// 错误次数
func (m *Data) ErrTimes() (int, error) {
	return m.super.GetInt(Key_ErrTimes)
}

func (m *Data) AddErrTimes() error {
	v, err := m.ErrTimes()
	if err != nil {
		return err
	}
	m.super.SetInt(Key_ErrTimes, v+1)
	return nil
}

// 局内出现过的最大球编号
func (m *Data) LargestBall() (int, error) {
	re, err := m.super.GetInt64(Key_LargestBall)
	return int(re), err
}

func (m *Data) SetLargestBall(v int) {
	m.super.SetInt64(Key_LargestBall, int64(v))
}

// 游戏是否已结束标识符
func (m *Data) IsGameEnd() (bool, error) {
	re, err := m.super.GetBool(Key_IsGameEnd)
	return re, err
}

func (m *Data) SetIsGameEnd(v bool) {
	m.super.SetBool(Key_IsGameEnd, v)
}

// 随机种子
func (m *Data) GameSeed() (int64, error) {
	return m.super.GetInt64(Key_GameSeed)
}

func (m *Data) SetGameSeed(v int64) {
	m.super.SetInt64(Key_GameSeed, v)
}

// 对局id
func (m *Data) GameId() (int64, error) {
	return m.super.GetInt64(Key_GameId)
}

func (m *Data) SetGameId(v int64) {
	m.super.SetInt64(Key_GameId, v)
}

// 游戏模式
func (m *Data) GameMode() (dwProto.GameMode, error) {
	re, err := m.super.GetInt(Key_GameMode)
	return dwProto.GameMode(re), err
}

func (m *Data) SetGameMode(v dwProto.GameMode) {
	m.super.SetInt(Key_GameMode, int(v))
}

// 场景中累计产出的球数
func (m *Data) BallCount() (int, error) {
	re, err := m.super.GetInt64(Key_BallCount)
	return int(re), err
}

func (m *Data) SetBallCount(v int) {
	m.super.SetInt64(Key_BallCount, int64(v))
}

// 主题id
func (m *Data) ThemeId() (int, error) {
	re, err := m.super.GetInt64(Key_ThemeId)
	return int(re), err
}

func (m *Data) SetThemeId(v int) {
	m.super.SetInt64(Key_ThemeId, int64(v))
}

// 胜利后可获得的奖励id
func (m *Data) RewardId() (int, error) {
	return m.super.GetInt(Key_RewardId)
}

func (m *Data) SetRewardId(v int) {
	m.super.SetInt(Key_RewardId, v)
}

// 场景中的全部球,分解成1级球的数量
func (m *Data) AllBalls() (int, error) {
	re, err := m.super.GetInt64(Key_AllBalls)
	return int(re), err
}

func (m *Data) SetAllBalls(v int) {
	m.super.SetInt64(Key_AllBalls, int64(v))
}

func (m *Data) GetString(key BlockType) (string, error) {
	return m.super.GetString(key)
}

// 获取数据块
func GetBlock(plyData *funcSless.PlayerData) (*Data, error) {

	bk, err := funcSless.GetBlock[BlockType](plyData, BlockName)
	if err != nil {
		return nil, err
	}

	return &Data{
		super: bk,
	}, nil
}
